/*
 * BaseAction
 *
 * Version information
 *
 * Feb 17, 2006
 *
 * Copyright (c) AmSoft Systems, 2006
 */

package net.amsoft.iservice.isso.webapp.struts.action;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.amsoft.iservice.isso.service.ISSOService;
import net.amsoft.iservice.isso.webapp.dataObject.IBrokerData;
import net.amsoft.iservice.isso.webapp.dataObject.LoginData;
import net.amsoft.iservice.util.IServiceUtil;
import net.amsoft.iservice.util.exception.IServiceException;
import static net.amsoft.iservice.util.IServiceConstants.*;
import static net.amsoft.iservice.isso.util.ISSOConstants.*;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import sun.misc.BASE64Encoder;

/**
 * @author rahul
 * 
 */
public abstract class BaseAction extends Action {
    public static Logger oLogger = Logger.getLogger(BaseAction.class);
    public final ActionForward execute(ActionMapping oMapping,
            ActionForm oForm, HttpServletRequest oRequest,
            HttpServletResponse oResponse) {

        preProcess(oMapping, oForm, oRequest, oResponse);
        ActionForward oForward = null;
        try {
            oForward = process(oMapping, oForm, oRequest, oResponse);
        } catch (Exception e) {
            oLogger.error("execute(): Exception: " + e.getMessage());
            return oMapping.findForward(CHKLOGIN_FWD);
        }
        postProcess(oMapping, oForm, oRequest, oResponse);
        return oForward;
    }

    private void preProcess(ActionMapping oMapping, ActionForm oForm,
            HttpServletRequest oRequest, HttpServletResponse oResponse) {
        // get the existing session
        oLogger.info("preProcess(): entry");
        HttpSession ohSession = oRequest.getSession(false);
        LoginData oLoginData = null;
        String sMachineCookie = null;
        String sSessionCookie = null;
        HashMap htSpLoginInfo = null;
         
        //Create Hashtable
        if (ohSession.getAttribute(SESSION_LOGIN_HASH_OBJ) == null) {
            htSpLoginInfo = new HashMap();
        } else {
            htSpLoginInfo = (HashMap) ohSession.getAttribute(SESSION_LOGIN_HASH_OBJ);
        }
        
        //Create LoginData object
        if (ohSession.getAttribute(SESSION_LOGIN_OBJ) == null) {
            oLoginData = new LoginData();
        } else {
            oLoginData = (LoginData) ohSession.getAttribute(SESSION_LOGIN_OBJ);
        }
        
        Cookie[] oCookie = oRequest.getCookies();
        if (oCookie != null) {
            for (int i = 0; i < oCookie.length; i++) {
                if (oCookie[i].getName().equals(MACHINE_COOKIE_NAME)) {
                    sMachineCookie = oCookie[i].getValue();
                    if (sSessionCookie != null)
                        break;
                }
                if (oCookie[i].getName().equals(SESSION_COOKIE_NAME)) {
                    sSessionCookie = oCookie[i].getValue();
                    if (sMachineCookie != null)
                        break;
                }
            }
        }
        oLoginData.setSessionCookie(sSessionCookie);
        oLoginData.setMachineCookie(sMachineCookie);
        ohSession.setAttribute(SESSION_LOGIN_OBJ, oLoginData);
        ohSession.setAttribute(SESSION_LOGIN_HASH_OBJ, htSpLoginInfo);
        
        Object oIBrokerData = ohSession.getAttribute(SESSION_IBROKER_OBJ);
        if (oIBrokerData == null) {
            oIBrokerData = new IBrokerData();
            loadIBrokerData((IBrokerData) oIBrokerData, oRequest
                    .getServerName());
            ohSession.setAttribute(SESSION_IBROKER_OBJ, oIBrokerData);
            oLogger.info("preProcess(): new IBrokerData created");
        }
        oLogger.info("preProcess(): exit");
    }// preProcess() ends

    public abstract ActionForward process(ActionMapping oMapping,
            ActionForm oForm, HttpServletRequest oRequest,
            HttpServletResponse oResponse) throws Exception;

    private void postProcess(ActionMapping oMapping, ActionForm oForm,
            HttpServletRequest oRequest, HttpServletResponse oResponse) {
    }

    protected boolean checkSpecialSPCase(HttpServletRequest oRequest,
            String ibrokerName, String spXRI) {
        return (getSPXri(ibrokerName).equals(spXRI) ? true : false);
    }

    protected String createArtifact(String providerID) {
        byte messageHandle[] = IServiceUtil.getSHABytes();
        byte[] sSourceID = IServiceUtil.getSHABytes(providerID);
        BASE64Encoder oEncoder = new BASE64Encoder();
        String sArtifact = oEncoder.encode(ARTIFACT_TYPE)
                + oEncoder.encode(messageHandle) + oEncoder.encode(sSourceID);
        oLogger.debug("createArtifact(): msgH: " + oEncoder.encode(messageHandle)
                + ", sID: " + oEncoder.encode(sSourceID) + ", art: "
                + sArtifact);
        oLogger.debug("createArtifact() : providerID=" + providerID+ ", ArtifactID=" + sArtifact);
        return sArtifact;
    }
    protected void setCookies(HttpServletResponse oResponse,
            String sSessionCookieVal, String sMachineCookieVal,
            boolean bRememberMe) {
        Cookie oMachineCookie = null;
        Cookie oSessionCookie = null;

        oSessionCookie = new Cookie(SESSION_COOKIE_NAME, sSessionCookieVal);
        oSessionCookie.setMaxAge(VALIDITY_SESSION_CLIENT);

        if (bRememberMe) {
            oMachineCookie = new Cookie(MACHINE_COOKIE_NAME, sMachineCookieVal);
            oMachineCookie.setMaxAge(VALIDITY_MACHINE_CLIENT);
        } else {
            oMachineCookie = new Cookie(MACHINE_COOKIE_NAME, "");
            oMachineCookie.setMaxAge(0);
        }
        //Secure cookies
//        oMachineCookie.setSecure(true);
//        oSessionCookie.setSecure(true);
        
        oMachineCookie.setPath("/");
        oSessionCookie.setPath("/");

        oResponse.addCookie(oSessionCookie);
        oResponse.addCookie(oMachineCookie);
        oLogger.debug("setCookies() : SessionCookie=" + sSessionCookieVal+ ", MachineCookie=" + sMachineCookieVal);
        
    }// Method : setCookies

    protected void removeCookie(HttpServletResponse oResponse,
            boolean forSession) {
        Cookie oCookie = (forSession)
                ? new Cookie(SESSION_COOKIE_NAME, null)
                : new Cookie(MACHINE_COOKIE_NAME, null);
        //oCookie.setSecure(true);
        oCookie.setMaxAge(0);
        oResponse.addCookie(oCookie);
        oLogger.info("removeCookie() : Message : Cookie Removed");
    }

    protected boolean verifyCookieState(String sGlobalInumber, String sCookie,
            boolean isSessionCookie) {
        try {
        	oLogger.info("verifyCookieState() : entry with data : GIN="+sGlobalInumber+", Cookie="+sCookie);
            return ISSOService.verifySessionState(sGlobalInumber, sCookie,
                    isSessionCookie, null, null);
        } catch (IServiceException ise) {
            oLogger.debug("verifyCookieState=false");
            return false;
        }
        
    }

    protected Map loadIBrokerData(IBrokerData oIBData, String ibrokerName) {
    	oLogger.debug("loadIBrokerData() : entry with data :IBrokeNname=" + ibrokerName);
        Map oIBMap = null;
        try {
            oIBMap = ISSOService.getIBrokerData(ibrokerName);
            if (oIBMap.keySet().contains(IB_BANNER_KEY)) {
                oIBData.setBannerLink((String) oIBMap.get(IB_BANNER_KEY));
                oIBMap.remove(IB_BANNER_KEY);
            }
        } catch (Exception e) {
            oLogger.error("loadIBrokerData(): Exception: " + e.getMessage());
        }
        oIBData.setIBrokerMap(oIBMap);
        return oIBMap;
    }
}